﻿// ***********************************************************************
// Assembly         : TSharp.Core
// Author           : tangjingbo
// Created          : 08-16-2013
//
// Last Modified By : tangjingbo
// Last Modified On : 09-26-2013
// ***********************************************************************
// <copyright file="PositionTagged.cs" company="">
//     Copyright (c) . All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using RazorEngine.Common;

namespace RazorEngine
{
    using System;
    using System.Diagnostics;

    /// <summary>
    /// Class PositionTagged
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [DebuggerDisplay("({Position})\"{Value}\"")]
    public class PositionTagged<T>
    {
        /// <summary>
        /// Prevents a default instance of the <see cref="PositionTagged{T}"/> class from being created.
        /// </summary>
        private PositionTagged()
        {
            Position = 0;
            Value = default(T);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PositionTagged{T}"/> class.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="offset">The offset.</param>
        public PositionTagged(T value, int offset)
        {
            Position = offset;
            Value = value;
        }

        /// <summary>
        /// Gets the position.
        /// </summary>
        /// <value>The position.</value>
        public int Position { get; private set; }
        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <value>The value.</value>
        public T Value { get; private set; }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
        /// </summary>
        /// <param name="obj">与当前的 <see cref="T:System.Object" /> 进行比较的 <see cref="T:System.Object" />。</param>
        /// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
        public override bool Equals(object obj)
        {
            PositionTagged<T> other = obj as PositionTagged<T>;
            return other != null &&
                   other.Position == Position &&
                   Equals(other.Value, Value);
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
        public override int GetHashCode()
        {
            return HashCodeCombiner.Start()
                .Add(Position)
                .Add(Value)
                .CombinedHash;
        }

        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
        public override string ToString()
        {
            return Value.ToString();
        }


        /// <summary>
        /// Performs an implicit conversion from <see>
        ///                                          <cref>PositionTagged{</cref>
        ///                                      </see>
        ///     to <see>
        ///                                                                           <cref>`0</cref>
        ///                                                                       </see>
        ///     .
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator T(PositionTagged<T> value)
        {
            return value.Value;
        }


        /// <summary>
        /// Performs an implicit conversion from <see>
        ///                                          <cref>Tuple{</cref>
        ///                                      </see>
        ///     to <see>
        ///                                                                  <cref>PositionTagged{`0}</cref>
        ///                                                              </see>
        ///     .
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator PositionTagged<T>(Tuple<T, int> value)
        {
            return new PositionTagged<T>(value.Item1, value.Item2);
        }

        /// <summary>
        /// Implements the ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(PositionTagged<T> left, PositionTagged<T> right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Implements the !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(PositionTagged<T> left, PositionTagged<T> right)
        {
            return !Equals(left, right);
        }
    }
}
